package com.visec.hdy.hadoop.inquiry;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.visec.hdy.hadoop.standard.FSB;

/**
 * 读取时间排序数据实现类
 * 
 * @author hdy
 *
 * @param <K>
 * @param <V>
 */
public class TimeLogInquiryImpl<V> extends DefaultInquiryImpl<String, V> {
	
	public static final String DEFAULT_CODE = "UTF-8";
	
	private static final String DELIMITER = "=";
	
	final Logger l = Logger.getLogger(TimeLogInquiryImpl.class);

	public TimeLogInquiryImpl(FSB fsb) {
		super(fsb);
	}

	public List<String> next(int i) {
		List<String> li = new ArrayList<>();
		int length = i;
		while (length > 0) {
			long read = context.read(length);
			if (read == -1)
				break;
			length -= read;
			try (InputStream is = fsb.get(context.getFile());
					BufferedReader br = new BufferedReader(new InputStreamReader(is, DEFAULT_CODE))) {
				Stream<String> limit = br.lines().skip(context.current() - read).limit(read);
				limit.forEach(li::add);
			} catch (Exception e) {
				l.error("", e);
			}
		}
		return li;
	}
	
	@Override
	public void queryAll() {
		List<File> sortFiles = context.sortFiles(fsb.listFiles(new File(context.getFolder())));
		context.setQueryFile(sortFiles);
	}

	@Override
	public void query(String start, String end) {
		List<File> sortFiles = context.sortFiles(fsb.listFiles(new File(context.getFolder())));
		List<File> files = new ArrayList<>();
		for (int i = 0; i < sortFiles.size(); i++) {
			String name = sortFiles.get(i).getName();
			if (name.compareTo(start) >= 0 && name.compareTo(end) <= 0) {
				if (files.isEmpty() && i > 0)
					files.add(sortFiles.get(i - 1));
				files.add(sortFiles.get(i));
			}
		}
		if (files.isEmpty() && (!sortFiles.isEmpty()))
			files.add(sortFiles.get(0));

		configStartCurrent(files.get(0), start);
		configEndCurrent(files.get(files.size() - 1), end);
		context.setQueryFile(files);
	}

	protected void configStartCurrent(File file, String start) {
		try (InputStream is = fsb.get(file);
				BufferedReader br = new BufferedReader(new InputStreamReader(is, DEFAULT_CODE))) {
			int i = 0;
			String line = br.readLine();
			while (line != null) {
				String[] split = line.split(DELIMITER);
				if (split.length < 2 || split[0].compareTo(start) >= 0) {
					break;
				}
				i++;
				line = br.readLine();
			}
			if (i <= context.count()) {
				context.setStartCurrent(i);
			}
		} catch (Exception e) {
			l.error("", e);
		}
	}

	protected void configEndCurrent(File file, String end) {
		try (InputStream is = fsb.get(file);
				BufferedReader br = new BufferedReader(new InputStreamReader(is, DEFAULT_CODE))) {
			int i = 0;
			String line = br.readLine();
			while (line != null) {
				String[] split = line.split(DELIMITER);
				if (split.length < 2 || split[0].compareTo(end) > 0) {
					break;
				}
				i++;
				line = br.readLine();
			}
			if (i < context.count()) {
				context.setEndCurrent(i);
			}
		} catch (Exception e) {
			l.error("", e);
		}
	}

	@Override
	public List<V> next(int i, Class<V> c) {
		List<String> next = next(i);
		List<V> re = new ArrayList<>();
		next.stream().forEach(a -> {
			if (a == null)
				return;
			String[] datas = a.split(DELIMITER);
			StringBuilder sb = new StringBuilder();
			for (int j = 1; j < datas.length; j++) {
				sb.append(DELIMITER).append(datas[j]);
			}
			try {
				V parseObject = JSONObject.parseObject(sb.substring(1), c);
				re.add(parseObject);
			} catch (Exception e) {
				l.error("", e);
			}
		});
		return re;
	}

	@Override
	public void queryLike(String like) {
		throw new UnsupportedOperationException();
	}
}
